local EmoTalentUtil = require "packages.emopack.pkg.emopack_talent.util" -- 加载战法核心
local skel = require "packages.emopack.pkg.emopack_talent.talents.core" ---@type SkillSkeleton

local hasTalent = EmoTalentUtil.hasTalent
local logTalent = EmoTalentUtil.logTalent
local invokeTalent = EmoTalentUtil.invokeTalent
local discoverTalent = EmoTalentUtil.discoverTalent
local forRandom = EmoTalentUtil.forRandom
local handleInvokedTalents = EmoTalentUtil.handleInvokedTalents
local getDynValue = EmoTalentUtil.getDynValue
local addDynValue = EmoTalentUtil.addDynValue
local timesCheckFilter = EmoTalentUtil.timesCheckFilter



--- 回复体力后
skel:addEffect(fk.HpRecover, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local room = player.room
    local cost_data = {}
    if target == player then -- 我回复体力
      if hasTalent(player, "emot_jichang") then -- 饥肠
        if player.phase ~= Player.NotActive then
          table.insert(cost_data, "emot_jichang")
        end
      end
      if hasTalent(player, "emot_jingang") then -- 金刚
        table.insert(cost_data, "emot_jingang")
      end
      if hasTalent(player, "emot_xuefengbao") then -- 血色风暴
        table.insert(cost_data, "emot_xuefengbao")
      end
    else -- 别人回复体力后
      if hasTalent(player, "emot_jisheng") and player:isEnemy(target) and not player.dead then -- 寄生
        table.insert(cost_data, "emot_jisheng")
      end
      if hasTalent(player, "emot_jihan") and player:isEnemy(target) and not player.dead and target.hp > 0 then -- 极寒
        table.insert(cost_data, "emot_jihan")
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_jichang") and not player.dead then -- 饥肠
      invokeTalent(player, "emot_jichang", event)
      room:changeMaxHp(player, data.num)
    end
    if table.contains(cost_data, "emot_jingang") and not player.dead then -- 金刚
      invokeTalent(player, "emot_jingang", event)
      room:changeShield(player, data.num)
    end
    if table.contains(cost_data, "emot_jihan") and target.hp > 0 then -- 极寒
      invokeTalent(player, "emot_jihan", event)
      room:damage { from = target, to = target, damage = 1, skillName = skel.name, damageType = fk.IceDamage }
    end
    if table.contains(cost_data, "emot_jisheng") and not player.dead then -- 寄生
      invokeTalent(player, "emot_jisheng", event)
      local num = math.min(data.num, target.maxHp)
      if num > 0 then
        room:changeMaxHp(target, -num)
        room:changeMaxHp(player, num)
      end
    end
    if table.contains(cost_data, "emot_xuefengbao") and forRandom(player, 0.2, "emot_xuefengbao") then -- 血色风暴
      for _, to in ipairs(room:getAllPlayers(true)) do
        if player:isEnemy(to) and not to.dead then
          invokeTalent(player, "emot_xuefengbao", event)
          room:doIndicate(player, {to})
          room:delay(200)
          room:damage { from = player, to = to, damage = data.num, skillName = skel.name }
        end
      end
    end
    handleInvokedTalents(player, event)
  end,
})

-- 回复体力前
skel:addEffect(fk.PreHpRecover, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local room = player.room
    if player.dead then return false end
    local cost_data = {}
    if target == player then -- 我回复体力
      if hasTalent(player, "emot_baofu") then -- 饱腹
        if player.phase == Player.NotActive then
          table.insert(cost_data, "emot_baofu")
        end
      end
    else -- 别人回复体力
      if hasTalent(player, "emot_fushi") and player:isEnemy(target) and target:getMark("emot_fushi-turn") == 0 then -- 腐蚀术
        table.insert(cost_data, "emot_fushi")
      end
      if hasTalent(player, "emot_nizhao") and player:isEnemy(target) and data.num > 1 then -- 泥沼
        table.insert(cost_data, "emot_nizhao")
      end
      if hasTalent(player, "emot_dutan") and player:isEnemy(target) and data.num > 1 and not data.card then -- 毒潭
        table.insert(cost_data, "emot_dutan")
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_baofu") then -- 饱腹
      invokeTalent(player, "emot_baofu", event)
      local num = getDynValue(player, "emot_baofu")
      addDynValue(player, "emot_baofu", 2)
      data.num = data.num + num
    end
    if table.contains(cost_data, "emot_dutan") and data.num > 0 then -- 毒潭
      invokeTalent(player, "emot_dutan", event)
      data:preventRecover()
    end
    if table.contains(cost_data, "emot_fushi") and data.num > 0 and target:getMark("emot_fushi-turn") == 0 then -- 腐蚀术
      room:setPlayerMark(target, "emot_fushi-turn", 1)
      invokeTalent(player, "emot_fushi", event)
      data:preventRecover()
    end
    if table.contains(cost_data, "emot_nizhao") and data.num > 1 then -- 泥沼
      invokeTalent(player, "emot_nizhao", event)
      data:changeRecover(1 - data.num)
    end
    handleInvokedTalents(player, event)
  end,
})


--- 失去体力前
skel:addEffect(fk.PreHpLost, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local cost_data = {}
    if target == player then
      if hasTalent(player, "emot_wuwo") and player:isKongcheng() then -- 无我相
        table.insert(cost_data, "emot_wuwo")
      end
      if hasTalent(player, "emot_wenyi") then -- 鹰嘴瘟医
        table.insert(cost_data, "emot_wenyi")
      end
    end
    if hasTalent(player, "emot_gaohuang") and player:isEnemy(target) then -- 病入膏肓
      table.insert(cost_data, "emot_gaohuang")
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_wuwo") then -- 无我相
      invokeTalent(player, "emot_wuwo", event)
      data:preventHpLost()
    end
    if table.contains(cost_data, "emot_wenyi") and data.num ~= 0 then -- 鹰嘴瘟医
      invokeTalent(player, "emot_wenyi", event)
      data:preventHpLost()
    end
    if table.contains(cost_data, "emot_gaohuang") then -- 病入膏肓
      invokeTalent(player, "emot_gaohuang", event)
      data.num = data.num * 2
    end
    handleInvokedTalents(player, event)
  end,
})

--- 失去体力后
skel:addEffect(fk.HpLost, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local cost_data = {}
    if hasTalent(player, "emot_duquan") and target ~= player and not player.dead then -- 毒泉
      table.insert(cost_data, "emot_duquan")
    end
    if hasTalent(player, "emot_dushe") and player:isEnemy(target) and not player.dead and not target:isNude() then -- 毒蛇
      table.insert(cost_data, "emot_dushe")
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_duquan") and player:isWounded() and not player.dead then -- 毒泉
      invokeTalent(player, "emot_duquan", event)
      room:recover { num = data.num, skillName = skel.name, who = player, recoverBy = player }
    end
    if table.contains(cost_data, "emot_dushe") and not player.dead and not target:isNude() then -- 毒蛇
      invokeTalent(player, "emot_dushe", event)
      room:obtainCard(player, table.random(target:getCardIds("he"), 3), false, fk.ReasonPrey, player, skel.name)
    end
    handleInvokedTalents(player, event)
  end,
})

--- 体力改变时
skel:addEffect(fk.HpChanged, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local cost_data = {}
    local damage = data.damageEvent
    if hasTalent(player, "emot_yinxue") and data.num < 0 and target.hp < 0 and damage and damage.from == player then -- 饮血刀
      table.insert(cost_data, "emot_yinxue")
    end
    if hasTalent(player, "emot_zhanjin") and data.num < 0 and target.hp < 1 and player:isEnemy(target) then -- 斩尽杀绝
      local check = damage ~= nil and damage.from == player
      if not check then
        local parent = player.room.logic:getCurrentEvent().parent
        if parent and parent.event == GameEvent.LoseHp then -- 失去体力也能触发
          parent = parent.parent
          if parent and parent.event == GameEvent.SkillEffect then
            ---@cast parent GameEvent.SkillEffect
            if parent.data.who == player then
              check = true
            end
          end
        end
      end
      if check then
        table.insert(cost_data, "emot_zhanjin")
      end
    end
    if target == player then -- 我改变体力
      if hasTalent(player, "emot_jiaotuo") and not player.dead then -- 交托与神
        table.insert(cost_data, "emot_jiaotuo")
      end
      if hasTalent(player, "emot_tudun") and not player.dead and data.num ~= 0
       and (player.hp == 1 or player.hp == player.maxHp) then -- 土遁术
        table.insert(cost_data, "emot_tudun")
      end
      if hasTalent(player, "emot_guijia") and data.num < 0 and not player.dead then -- 龟甲
        table.insert(cost_data, "emot_guijia")
      end
      if hasTalent(player, "emot_budong") and data.shield_lost and data.shield_lost > 0
       and player.shield > 0 and not player.dead then -- 不动如山
        table.insert(cost_data, "emot_budong")
      end
    else -- 其他角色改变体力
      if hasTalent(player, "emot_chuanshan") and not player.dead and damage and damage.from == player
       and data.shield_lost and data.shield_lost > 0 and player:isEnemy(target) then -- 穿山甲
        table.insert(cost_data, "emot_chuanshan")
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_yinxue") then -- 饮血刀(不算发动)
      --logTalent(player, "emot_yinxue")
      room:addPlayerMark(player, "emot_yinxue", -target.hp)
    end
    --- 实际操作
    if table.contains(cost_data, "emot_jiaotuo") and not player.dead then -- 交托与神
      room:addPlayerMark(player, "emot_jiaotuo", math.abs(data.num))
      local num = player:getMark("emot_jiaotuo") // 3
      if num > 0 then
        invokeTalent(player, "emot_jiaotuo", event)
        room:removePlayerMark(player, "emot_jiaotuo", 3 * num)
        for _ = 1, num do
          discoverTalent(player, { rarity_limit = {1, 2}, random = true })
          if player.dead then break end
        end
      end
    end
    if table.contains(cost_data, "emot_guijia") and not player.dead then -- 龟甲
      invokeTalent(player, "emot_guijia", event)
      room:changeShield(player, math.abs(data.num))
    end
    if table.contains(cost_data, "emot_tudun") and not player.dead then -- 土遁术
      invokeTalent(player, "emot_tudun", event)
      player:drawCards(3, skel.name)
    end
    if table.contains(cost_data, "emot_budong") and not player.dead then -- 不动如山
      invokeTalent(player, "emot_budong", event)
      room:changeShield(player, 1)
    end
    if table.contains(cost_data, "emot_chuanshan") and not player.dead then -- 穿山甲
      local num = data.shield_lost
      if num and num > 0 then
        invokeTalent(player, "emot_chuanshan", event)
        room:changeShield(player, num)
      end
    end
    if table.contains(cost_data, "emot_zhanjin") and not target.dead then -- 斩尽杀绝：令其立即死亡，晚点执行
      invokeTalent(player, "emot_zhanjin", event)
      room:killPlayer{
        who = target,
        killer = player,
        damage = data.damageEvent,
      }
    end
    handleInvokedTalents(player, event)
  end,
})

--- 失去体力上限前
skel:addEffect(fk.BeforeMaxHpChanged, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local cost_data = {}
    if target == player then
      if hasTalent(player, "emot_wenyi") and data.num < 0 then -- 鹰嘴瘟医
        table.insert(cost_data, "emot_wenyi")
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_wenyi") and data.num < 0 then -- 鹰嘴瘟医
      invokeTalent(player, "emot_wenyi", event)
      data:preventMaxHpChange()
    end
    handleInvokedTalents(player, event)
  end,
})
